﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.Linq;
using System.IO;
using McMaster.Extensions.CommandLineUtils;

namespace PngIntoBundle
{

    public class Constants
    {
        public const int DefaultSizeY = 128;
        public const int DefaultSizeX = 128;
        public const int BundlxStartPaddingBytes = 16;
        public const int BundlxEndPaddingBytes = 16;
        //bundle文件开头偏移
        public const int BundleStartPaddingBytes = 160;
        //bundlx文件大小
        public const int BundlxFileLength = 81952;

    }

    class Program
    {
        [Option(Description = "某个级别的路径,如\"...\\Layers\\_alllayers\\L05\" ", ShortName = "p")]
        public string Path { get; set; } = $@"C:\OCNwork\arcgisbundle\worldpng\Layers\_alllayers\L08";
        [Option(Description = "输出路径,如\"...\\Layers\\_alllayers\\L05\" ", ShortName = "op")]
        public string OutPath { get; set; } = $@"C:\OCNwork\arcgisbundle\worldpng\Layers\_alllayers\L08";

        static void Main(string[] args)
        {
            CommandLineApplication.Execute<Program>(args);
        }
        public void OnExecute()
        {
            var rootPathDirInfo = new DirectoryInfo(Path);
            var dirsOfRows = rootPathDirInfo.GetDirectories("*", SearchOption.TopDirectoryOnly);
            //排序
            dirsOfRows.ToList().Sort((a, b) =>
            {
                return (Utils.ExtractIntForFolderOfFileName(a.Name) - Utils.ExtractIntForFolderOfFileName(b.Name));
            });
            dirsOfRows.ToList().ForEach((dir) =>
            {
                int rowNumber = Utils.ExtractIntForFolderOfFileName(dir.Name);
                FileInfo[] pngFileInfos = dir.GetFiles();
                pngFileInfos.ToList().ForEach((pngFileInfo) =>
                {
                    int colNumber = Utils.ExtractIntForFolderOfFileName(pngFileInfo.Name);
                    int colGroupNumber = colNumber / Constants.DefaultSizeX;
                    int rowGroupNumber = rowNumber / Constants.DefaultSizeY;
                    string bundleBase = $"R{ (rowGroupNumber * Constants.DefaultSizeY).ToString("X4")}C{(colGroupNumber * Constants.DefaultSizeX).ToString("X4")}";
                    string bundleFileName = System.IO.Path.Combine(this.OutPath, $"{bundleBase}.bundle");
                    string bundlxFileName = System.IO.Path.Combine(this.OutPath, $"{bundleBase}.bundlx");
                    FileInfo bundleFileInfo = new FileInfo(bundleFileName);
                    FileInfo bundlxFileInfo = new FileInfo(bundlxFileName);
                    if (bundlxFileInfo.Exists == false)
                    {
                        var fileStream = bundlxFileInfo.Create();
                        fileStream.Write(new byte[Constants.BundlxFileLength], 0, Constants.BundlxFileLength);
                        fileStream.Close();
                    }
                    if (bundleFileInfo.Exists == false)
                    {
                        var fileStream = bundleFileInfo.Create();
                        fileStream.Write(new byte[Constants.BundleStartPaddingBytes], 0, Constants.BundleStartPaddingBytes);
                        fileStream.Close();
                    }

                    //该png文件再该分区的相对行和列
                    int relativeColNumber = colNumber - Constants.DefaultSizeX * colGroupNumber;
                    int relativeRowNumber = rowNumber - Constants.DefaultSizeY * rowGroupNumber;
                    //每个bundlx文件都一样大81920+32字节，前后16个描述信息，剩下的是可用信息，并且以每5个字节重复，存储了对应的图片在bundle文件中的偏移量。并且bundlx文件存储图片偏移量信息的顺序是按列存储。
                    int positionToStoreOffsetOfThisPngInBundlx = Constants.BundlxStartPaddingBytes + 5 * (relativeRowNumber + relativeColNumber * Constants.DefaultSizeY);

                    //long offset = (long)(buffer[0] & 0xff) + (long)(buffer[1] & 0xff)
                    // * 256 + (long)(buffer[2] & 0xff) * 65536
                    //+ (long)(buffer[3] & 0xff) * 16777216
                    // + (long)(buffer[4] & 0xff) * 4294967296L;

                    long fileLength = pngFileInfo.Length;
                    byte[] bytesOfFileLength = BitConverter.GetBytes((int)fileLength);

                    using (var bdFileStream = bundleFileInfo.Open(FileMode.Open, FileAccess.Write))
                    {
                        bdFileStream.Seek(0, SeekOrigin.End);
                        //png文件流在bundle文件的偏移量
                        long offsetOfThisPng = bdFileStream.Position;
                        bdFileStream.Write(bytesOfFileLength, 0, 4);
                        using (var pngFileStream = pngFileInfo.OpenRead())
                        {
                            var bytesOfPngFile = new byte[pngFileStream.Length];
                            pngFileStream.Read(bytesOfPngFile, 0, (int)pngFileStream.Length);
                            bdFileStream.Write(bytesOfPngFile, 0, bytesOfPngFile.Length);
                        }
                        bdFileStream.Close();

                        var bytesOfOffsetOfPngFile = BitConverter.GetBytes((int)offsetOfThisPng);
                        using (var bxFileStream = bundlxFileInfo.Open(FileMode.Open, FileAccess.Write))
                        {
                            ;
                            bxFileStream.Seek(positionToStoreOffsetOfThisPngInBundlx, SeekOrigin.Begin);
                            bxFileStream.Write(bytesOfOffsetOfPngFile, 0, 4);
                            bxFileStream.Write(new byte[] { 0 }, 0, 1);
                            bxFileStream.Close();
                        }


                    }






                    //StreamWriter bdStreamWriter = new StreamWriter(bundleFileInfo.OpenWrite());




                    //StreamWriter bundlxStreamWriter = new StreamWriter(bundlxFileInfo.OpenWrite());



                });




            });
            ;

            //integers.ToList().Sort();
            //每一行
            //integers.ToList().ForEach((rowNumber) =>
            //{



            //});


            //Utils.ExtractIntForFolderOfFileName(dirsOfRows[0].Name);



            ;
        }
    }

    public class Utils
    {
        public static int ExtractIntForFolderOfFileName(string folderOrFilename)
        {
            // $"L{Z:D2}/R{Y.ToString("X8").ToLower()}/C{X.ToString("X8").ToLower()}.png";
            var removed = folderOrFilename.Remove(0, 1);
            removed = removed.ToUpper().Split('.')[0];
            //int.Parse(  folderOrFilename,System.Globalization.NumberStyles.  )
            var extractedNumber = int.Parse(removed, System.Globalization.NumberStyles.HexNumber);
            return extractedNumber;
        }
    }


}
